Spring Boot ORM-এ Hibernate এর Lazy এবং Eager Loading হলো ডেটা লোড করার দুটি ভিন্ন পদ্ধতি। এই পদ্ধতিগুলো ব্যবহার করে ডাটাবেস থেকে সম্পর্কযুক্ত ডেটা (related data) লোড করা হয়।
Lazy Loading
Lazy Loading হলো একটি ডেটা লোডিং পদ্ধতি যেখানে সম্পর্কযুক্ত ডেটা (related data) তখনই ডাটাবেস থেকে লোড হয় যখন এটি সত্যিকার অর্থে প্রয়োজন হয়। এটি ডিফল্টভাবে ব্যবহার করা হয় এবং মেমোরি ব্যবহারের ক্ষেত্রে কার্যকর।
বৈশিষ্ট্য
- সম্পর্কযুক্ত ডেটা শুধুমাত্র চাহিদার ভিত্তিতে লোড হয়।
- মেমোরি এবং নেটওয়ার্ক ব্যবহারে দক্ষ।
- বড় ডাটাসেটের ক্ষেত্রে উপযোগী।
উদাহরণ
import jakarta.persistence.*;
import java.util.List;
@Entity
public class Category {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "category", fetch = FetchType.LAZY)
private List<Product> products;
// Getters and Setters
}
উপরের উদাহরণে, Category এর সাথে সম্পর্কযুক্ত Product গুলো তখনই লোড হবে যখন getProducts() মেথড কল করা হবে।
Eager Loading
Eager Loading হলো একটি ডেটা লোডিং পদ্ধতি যেখানে সম্পর্কযুক্ত ডেটা (related data) ডাটাবেস থেকে সাথে সাথেই লোড হয়, অর্থাৎ প্রাথমিক কুয়েরির সাথে সম্পর্কিত ডেটাও নিয়ে আসে।
বৈশিষ্ট্য
- সম্পর্কযুক্ত ডেটা লোড হতে দেরি হয় না।
- বড় ডাটাসেটে অপ্রয়োজনীয় ডেটা লোড করে পারফরম্যান্সে প্রভাব ফেলতে পারে।
- ব্যবহার করা উচিত যেখানে সম্পর্কযুক্ত ডেটা সবসময় প্রয়োজন।
উদাহরণ
import jakarta.persistence.*;
import java.util.List;
@Entity
public class Category {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "category", fetch = FetchType.EAGER)
private List<Product> products;
// Getters and Setters
}
এখানে, Category এর সাথে সম্পর্কিত Product গুলো প্রাথমিক কুয়েরির সাথেই লোড হয়ে যাবে।
FetchType এর ব্যবহার
Hibernate-এ @OneToMany, @ManyToOne, @OneToOne, এবং @ManyToMany সম্পর্কিত অ্যানোটেশনগুলোর সাথে fetch অ্যাট্রিবিউট ব্যবহার করে Lazy এবং Eager Loading নির্ধারণ করা হয়।
FetchType Enum
FetchType.LAZY: Lazy Loading সক্রিয় করে।FetchType.EAGER: Eager Loading সক্রিয় করে।
উদাহরণ
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private Double price;
@ManyToOne(fetch = FetchType.LAZY)
private Category category;
// Getters and Setters
}
উপরের উদাহরণে, Product এর সাথে সম্পর্কিত Category তখনই লোড হবে যখন getCategory() মেথড কল করা হবে।
Lazy এবং Eager Loading এর তুলনা
| বৈশিষ্ট্য | Lazy Loading | Eager Loading |
|---|---|---|
| ডেটা লোডিং টাইমিং | প্রয়োজন অনুসারে লোড হয়। | তৎক্ষণাৎ লোড হয়। |
| মেমোরি ব্যবহারে দক্ষতা | বেশি কার্যকর। | কম কার্যকর। |
| ডেটা অ্যাক্সেস টাইমিং | শুধুমাত্র ব্যবহার করা হলে লোড হয়। | সব ডেটা একসাথে লোড হয়। |
| উপযোগিতা | বড় ডাটাসেট এবং কমনীয় অপারেশনে ভালো। | ছোট ডেটাসেট এবং সম্পর্কযুক্ত ডেটা প্রয়োজন হলে ভালো। |
LazyInitializationException সমস্যার সমাধান
Lazy Loading ব্যবহারে Hibernate মাঝে মাঝে LazyInitializationException এর সম্মুখীন হতে পারে। এই সমস্যা সমাধানের জন্য নিচের পদ্ধতিগুলো ব্যবহার করা যেতে পারে:
- Transactional Annotation ব্যবহার:
@Transactionalঅ্যানোটেশন ব্যবহার করে Lazy Loading এর জন্য ডেটাবেস সেশন সক্রিয় রাখুন।
@Service
@Transactional
public class CategoryService {
public List<Product> getProducts(Category category) {
return category.getProducts();
}
}
- Join Fetch ব্যবহার:
Spring Data JPA-তে@QueryএবংJOIN FETCHব্যবহার করে সম্পর্কযুক্ত ডেটা প্রি-লোড করুন।
@Query("SELECT c FROM Category c JOIN FETCH c.products WHERE c.id = :id")
Category findCategoryWithProducts(@Param("id") Long id);
Lazy এবং Eager Loading ব্যবহার কবে করবেন?
- Lazy Loading: যখন ডেটা সবসময় ব্যবহার হবে না বা কেবলমাত্র নির্দিষ্ট পরিস্থিতিতে প্রয়োজন।
- Eager Loading: যখন সম্পর্কযুক্ত ডেটা প্রয়োজনীয় এবং তা প্রতিবারই ব্যবহৃত হবে।
Hibernate এবং Spring Boot ORM-এর এই দুটি লোডিং কৌশল ডেভেলপারদের ডেটা লোডিংয়ের সময় এবং মেমোরি ব্যবহারের কার্যকারিতা নিশ্চিত করে।
Spring Boot ORM এর গুরুত্বপূর্ণ ফিচারগুলোর একটি হল Lazy Loading এবং Eager Loading, যা ডেটাবেস থেকে ডেটা রিট্রিভ করার সময় ডেটার লোডিং স্ট্র্যাটেজি নির্ধারণ করে। Hibernate (Spring Data JPA এর ডিফল্ট ইমপ্লিমেন্টেশন) এই দুই লোডিং কৌশল সরবরাহ করে।
Lazy Loading
Lazy Loading হল এমন একটি লোডিং পদ্ধতি যেখানে ডেটা শুধুমাত্র যখন প্রয়োজন হয় তখনই ডেটাবেস থেকে রিট্রিভ করা হয়।
বৈশিষ্ট্য
- ডেটা ডিফার্ড বা বিলম্বিত ভাবে লোড করা হয়।
- মেমোরি এবং পারফরম্যান্সের জন্য কার্যকর, কারণ অপ্রয়োজনীয় ডেটা লোড হয় না।
- Hibernate এর ডিফল্ট লোডিং কৌশল।
উদাহরণ
@Entity
public class Category {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "category", fetch = FetchType.LAZY)
private List<Product> products;
// Getters and Setters
}
উপরের উদাহরণে Category থেকে Product লোড হবে না যতক্ষণ না getProducts() মেথড কল করা হয়।
ব্যবহার
Category category = categoryRepository.findById(1L).orElse(null);
System.out.println(category.getName()); // এখানে শুধুমাত্র `Category` টেবিল থেকে ডেটা লোড হবে।
System.out.println(category.getProducts()); // এখানে `Product` টেবিল থেকে ডেটা লোড হবে।
Eager Loading
Eager Loading হল এমন একটি লোডিং পদ্ধতি যেখানে সম্পর্কিত সমস্ত ডেটা প্রথম রিকোয়েস্টেই ডেটাবেস থেকে রিট্রিভ করা হয়।
বৈশিষ্ট্য
- ডেটা প্রাথমিকভাবে লোড করা হয়।
- কোড লেখার সময় সহজ মনে হলেও, অনেক ক্ষেত্রে অপ্রয়োজনীয় ডেটা লোড করার ফলে পারফরম্যান্স কমে যেতে পারে।
- স্পষ্টতভাবে
FetchType.EAGERব্যবহার করে কনফিগার করা যায়।
উদাহরণ
@Entity
public class Category {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "category", fetch = FetchType.EAGER)
private List<Product> products;
// Getters and Setters
}
উপরের উদাহরণে Category লোড করার সময় সম্পর্কিত Product ডেটাও লোড হবে।
ব্যবহার
Category category = categoryRepository.findById(1L).orElse(null);
System.out.println(category.getName()); // এখানে `Category` এবং `Product` উভয় টেবিল থেকে ডেটা লোড হবে।
Lazy এবং Eager Loading এর তুলনা
| বৈশিষ্ট্য | Lazy Loading | Eager Loading |
|---|---|---|
| ডেটা লোডিং টাইম | প্রয়োজন হলে ডেটা লোড করা হয়। | সম্পর্কিত ডেটা তাৎক্ষণিক লোড করা হয়। |
| মেমোরি ব্যবহারে কার্যকারিতা | বেশি কার্যকর, কারণ অপ্রয়োজনীয় ডেটা লোড হয় না। | কম কার্যকর, কারণ অপ্রয়োজনীয় ডেটা লোড হয়। |
| কনফিগারেশন ডিফল্ট | FetchType.LAZY | FetchType.EAGER |
| ব্যবহার ক্ষেত্র | বড় সম্পর্কিত ডেটাসেট যেখানে সবসময় ডেটা প্রয়োজন হয় না। | ছোট সম্পর্কিত ডেটাসেট যেখানে সবসময় ডেটা প্রয়োজন। |
| পারফরম্যান্স | কুয়েরি সংখ্যা বেশি হতে পারে। | বড় ডেটাসেটের ক্ষেত্রে ধীরগতি হতে পারে। |
Lazy এবং Eager Loading এর চ্যালেঞ্জ
Lazy Loading:
- LazyInitializationException: যখন Hibernate সেশন বন্ধ হয়ে যায় এবং Lazy ডেটা অ্যাক্সেস করা হয়।
- অতিরিক্ত কুয়েরি: একাধিক Lazy লোডিং কুয়েরি তৈরি হতে পারে।
Eager Loading:
- অপ্রয়োজনীয় ডেটা লোড: যদি লোড করা ডেটা ব্যবহার না হয়, মেমোরি এবং পারফরম্যান্সের ক্ষতি হয়।
- জটিল কুয়েরি: Eager লোডিং বড় ডেটাসেটের জন্য জটিল কুয়েরি তৈরি করতে পারে।
Practical Scenario
Lazy Loading উদাহরণ:
আপনার যদি Category এবং Product এর মধ্যে অনেক সম্পর্ক থাকে এবং Product সবসময় প্রয়োজন না হয়, তাহলে Lazy Loading উপযুক্ত।
Eager Loading উদাহরণ:
যদি সম্পর্কিত ডেটা সবসময় প্রয়োজন হয়, যেমন Order এবং OrderDetails এর ক্ষেত্রে, তাহলে Eager Loading ব্যবহার করা যেতে পারে।
সারাংশ
Lazy Loading এবং Eager Loading এর মধ্যে নির্বাচন নির্ভর করে অ্যাপ্লিকেশনের প্রয়োজনীয়তা এবং ডেটাবেসের স্ট্রাকচারের উপর। Lazy Loading ডেটার ব্যবহার কম হলে কার্যকর, আর Eager Loading যেখানে ডেটা সবসময় প্রয়োজন সেখানে উপযুক্ত। Spring Boot এবং Hibernate এই দুই কৌশল কনফিগার করতে ডেভেলপারদের পুরো স্বাধীনতা প্রদান করে।
স্প্রিং ডেটা JPA এবং Hibernate-এ FetchType.LAZY এবং FetchType.EAGER হলো ডেটা লোডিং স্ট্র্যাটেজি যা Entity সম্পর্কিত ডেটা কীভাবে ডেটাবেজ থেকে রিট্রিভ করা হবে তা নির্ধারণ করে। এই দুইটি স্ট্র্যাটেজি মূলত @OneToOne, @OneToMany, @ManyToOne, এবং @ManyToMany অ্যানোটেশনের সাথে ব্যবহার করা হয়।
FetchType.LAZY
FetchType.LAZY এর মানে হলো ডেটা তখনই ডেটাবেজ থেকে রিট্রিভ করা হবে, যখন এটি প্রথমবার অ্যাক্সেস করা হবে। অর্থাৎ, সম্পর্কিত ডেটা শুধুমাত্র প্রয়োজনের সময় লোড করা হয়। এটি ডেটাবেস থেকে অপ্রয়োজনীয় ডেটা লোডিং এড়িয়ে কার্যক্ষমতা বাড়াতে সাহায্য করে।
ব্যবহার:
@Entity
public class Department {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "department", fetch = FetchType.LAZY)
private List<Employee> employees;
// Getters and Setters
}
বৈশিষ্ট্য:
- সম্পর্কিত ডেটা রিফারেন্স করলে তখনই ডেটাবেজ থেকে ফেচিং হবে।
- পারফরম্যান্স বৃদ্ধি পায় কারণ প্রথমবার মেইন ডেটা লোড করার সময় সম্পর্কিত ডেটা লোড হয় না।
- ডেটাবেজ অ্যাক্সেসের সংখ্যা বৃদ্ধি পেতে পারে, যদি সম্পর্কিত ডেটা একাধিকবার প্রয়োজন হয়।
উদাহরণ:
Department department = departmentRepository.findById(1L).get();
// এই লাইন সম্পর্কিত Employee লোড করবে না
List<Employee> employees = department.getEmployees();
// এই লাইন Employee লোড করবে কারণ এখানে অ্যাক্সেস করা হচ্ছে
FetchType.EAGER
FetchType.EAGER এর মানে হলো Entity লোড করার সময় তার সম্পর্কিত ডেটাও সঙ্গে সঙ্গে ডেটাবেজ থেকে রিট্রিভ করা হবে। এটি তখন ব্যবহার করা হয় যখন সম্পর্কিত ডেটা প্রায়শই প্রয়োজন হয়।
ব্যবহার:
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "department_id")
private Department department;
// Getters and Setters
}
বৈশিষ্ট্য:
- মেইন ডেটা রিট্রিভ করার সময় সম্পর্কিত ডেটাও একসঙ্গে লোড হয়।
- পারফরম্যান্স কমে যেতে পারে যদি সম্পর্কিত ডেটা অনেক বড় এবং তা প্রয়োজন না হয়।
- ডেটাবেজ অ্যাক্সেসের সংখ্যা কমে যায় কারণ এটি একবারেই ডেটা লোড করে।
উদাহরণ:
Employee employee = employeeRepository.findById(1L).get();
// এই লাইন Employee এবং তার Department উভয়ই লোড করবে
Department department = employee.getDepartment();
FetchType.LAZY বনাম FetchType.EAGER
| বৈশিষ্ট্য | FetchType.LAZY | FetchType.EAGER |
|---|---|---|
| লোডিং সময় | ডেটা প্রথমবার প্রয়োজন হলে লোড হয়। | ডেটা Entity লোড করার সময় লোড হয়। |
| পারফরম্যান্স | কম মেমোরি ব্যবহার এবং দ্রুত লোডিং। | বড় সম্পর্কিত ডেটার ক্ষেত্রে ধীর হতে পারে। |
| ডেটাবেস অ্যাক্সেস | প্রয়োজন অনুসারে একাধিকবার অ্যাক্সেস। | একবারেই সম্পর্কিত ডেটা অ্যাক্সেস। |
| ব্যবহারযোগ্যতা | যখন সম্পর্কিত ডেটা কম ব্যবহৃত হয়। | যখন সম্পর্কিত ডেটা প্রায়শই ব্যবহৃত হয়। |
FetchType এর ব্যবহার স্থান নির্বাচন
- FetchType.LAZY:
- সম্পর্কিত ডেটা বড় হলে এবং তা খুব কম ব্যবহৃত হলে।
- যখন পারফরম্যান্স গুরুত্বপূর্ণ।
- ডেটা রিলেশনাল স্ট্রাকচারে কাজ করার সময়।
- FetchType.EAGER:
- যখন সম্পর্কিত ডেটা ছোট এবং প্রায়ই ব্যবহার হয়।
- সম্পর্কিত ডেটা অ্যাক্সেস নিশ্চিত করতে হবে।
ডিফল্ট ফেচ টাইপ
- @OneToMany এবং @ManyToMany: ডিফল্ট হলো FetchType.LAZY।
- @OneToOne এবং @ManyToOne: ডিফল্ট হলো FetchType.EAGER।
সারাংশ
FetchType.LAZY এবং FetchType.EAGER JPA এবং Hibernate-এ ডেটা লোডিং কৌশল নির্ধারণ করে। LAZY পারফরম্যান্স উন্নত করতে সাহায্য করে, যখন EAGER প্রয়োজনীয় ডেটা লোডিং নিশ্চিত করে। ব্যবহারের স্থান অনুযায়ী সঠিক FetchType নির্বাচন করা অ্যাপ্লিকেশনের কার্যকারিতা এবং রিসোর্স ব্যবহারের জন্য অত্যন্ত গুরুত্বপূর্ণ।
স্প্রিং বুট ORM-এ Lazy Loading হলো ডেটাবেস থেকে শুধুমাত্র প্রয়োজনীয় ডেটা লোড করার একটি কৌশল। এটি পারফরম্যান্স অপ্টিমাইজ করার জন্য ব্যবহৃত হয়। Lazy Loading ডেটাবেস থেকে ডেটা তখনই রিট্রিভ করে, যখন সেটি অ্যাপ্লিকেশন কোডে সত্যিকারভাবে প্রয়োজন হয়।
Lazy Loading কী?
Lazy Loading হলো একটি ডেটা-লোডিং স্ট্র্যাটেজি, যেখানে সম্পর্কিত ডেটা বা অ্যাসোসিয়েশন (Associations) তখনই লোড হয়, যখন সেটি অ্যাক্সেস করা হয়। এর বিপরীতে, Eager Loading সব সম্পর্কিত ডেটা একবারেই লোড করে।
উদাহরণ:
একটি User এবং Orders এর মধ্যে এক-থেকে-অনেক (One-to-Many) সম্পর্ক রয়েছে। Lazy Loading ব্যবহার করলে Orders তখনই লোড হবে, যখন সরাসরি user.getOrders() মেথড কল করা হবে।
স্প্রিং বুটে Lazy Loading কনফিগারেশন
Lazy Loading সক্রিয় করতে Hibernate এবং JPA ডিফল্ট কনফিগারেশন ব্যবহার করে। এটি সাধারণত @OneToMany, @ManyToOne, বা অন্যান্য অ্যাসোসিয়েশন এনোটেশনের মাধ্যমে কনফিগার করা হয়।
উদাহরণ: Lazy Loading এনোটেশন
Entity: User
import jakarta.persistence.*;
import java.util.List;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY) // Lazy Loading
private List<Order> orders;
// Getters and Setters
}
Entity: Order
import jakarta.persistence.*;
@Entity
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String product;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
// Getters and Setters
}
Lazy Loading এর কার্যপ্রক্রিয়া
Lazy Loading লোডিং প্যাটার্ন
User user = userRepository.findById(1L).orElse(null);
// Orders তখনই লোড হবে, যখন getOrders() কল করা হবে
List<Order> orders = user.getOrders();
Lazy Loading SQL ট্রেস
userRepository.findById()কল করলেUser-এর জন্য একটি সিলেক্ট কোয়েরি চলবে।user.getOrders()কল করলে অন্য একটি কোয়েরি চালিয়েOrdersরিট্রিভ হবে।
Eager Loading-এর তুলনা
Eager Loading-এ userRepository.findById()-এ User এবং Orders উভয়ের জন্যই একবারেই কোয়েরি চালানো হয়।
Lazy Loading ব্যবহারের সুবিধা
- পারফরম্যান্স অপ্টিমাইজেশন
বড় এবং কমপ্লেক্স ডেটা লোড না করে শুধুমাত্র প্রয়োজনীয় ডেটা লোড করা যায়, যা মেমোরি ব্যবহারে কার্যকর। - ডেটাবেস লোড কমানো
প্রাথমিক পর্যায়ে সব ডেটা লোড না করার কারণে ডেটাবেসে অপ্রয়োজনীয় লোড কমে যায়। - ফ্লেক্সিবিলিটি
Lazy Loading ব্যবহার করে সম্পর্কিত ডেটা তখনই লোড করা যায়, যখন অ্যাপ্লিকেশনের লজিকে প্রয়োজন।
Lazy Loading ব্যবহারে সতর্কতা
LazyInitializationException
যদি Hibernate Session বন্ধ হয়ে যায় এবং তারপর Lazy লোড করা ডেটা অ্যাক্সেস করার চেষ্টা করা হয়, তবে LazyInitializationException দেখা দেয়।সমাধান:
Transaction Management ব্যবহার করুন:
Lazy ডেটা লোড করার সময় ট্রানজ্যাকশন সক্রিয় রাখুন।@Transactional public List<Order> getUserOrders(Long userId) { User user = userRepository.findById(userId).orElse(null); return user.getOrders(); }- DTO বা Projections ব্যবহার করুন:
Lazy লোডিংয়ের পরিবর্তে প্রয়োজনীয় ডেটা সরাসরি রিট্রিভ করার জন্য DTO ব্যবহার করতে পারেন।
অতিরিক্ত কোয়েরি
অনেক Lazy ফিল্ড অ্যাক্সেস করলে একাধিক ডাটাবেস কোয়েরি চালানোর কারণে পারফরম্যান্সে প্রভাব পড়তে পারে।সমাধান:
Batch Fetching ব্যবহার করুন:
Hibernate এর batch_size কনফিগার করে Lazy ডেটা একাধিক রেকর্ডে একবারে লোড করতে পারেন।spring.jpa.properties.hibernate.default_batch_fetch_size=10
Lazy Loading এবং Eager Loading এর তুলনা
| Lazy Loading | Eager Loading |
|---|---|
| প্রয়োজনীয় ডেটা তখনই লোড হয়, যখন সেটি অ্যাক্সেস করা হয়। | সব সম্পর্কিত ডেটা একবারেই লোড হয়। |
| পারফরম্যান্স অপ্টিমাইজেশনের জন্য কার্যকর। | বড় ডেটাসেটের ক্ষেত্রে মেমোরি লোড বেশি। |
| অতিরিক্ত কোয়েরি তৈরি হতে পারে। | কম কোয়েরি তৈরি হয়। |
সারাংশ
Lazy Loading ডেটাবেস অপারেশনে কর্মক্ষমতা (Performance) উন্নত করার একটি কার্যকরী পদ্ধতি, বিশেষত যখন বড় ডেটাসেট বা কমপ্লেক্স রিলেশন নিয়ে কাজ করা হয়। তবে এটি ব্যবহারে সতর্কতা প্রয়োজন, কারণ অযথা LazyInitializationException বা অতিরিক্ত কোয়েরি চালানোর সমস্যা হতে পারে। সঠিক ট্রানজ্যাকশন ম্যানেজমেন্ট এবং Hibernate-এর কনফিগারেশন অপ্টিমাইজেশনের মাধ্যমে Lazy Loading কার্যকরভাবে ব্যবহার করা যায়।
Lazy এবং Eager Loading কি?
Spring Boot ORM, বিশেষ করে Hibernate-এ Lazy Loading এবং Eager Loading হলো ডেটাবেজ থেকে ডেটা ফেচ করার দুটি কৌশল।
Lazy Loading
- Lazy Loading হলো তখনই ডেটা লোড করা, যখন সেটি ব্যবহার করা হয়। এটি ডেটা লোড করার সময় কমায় এবং মেমরি ব্যবহার অপ্টিমাইজ করে।
- Hibernate-এ
FetchType.LAZYডিফল্ট ফেচ টাইপ।
Eager Loading
- Eager Loading হলো প্রথমবারেই সম্পর্কিত সমস্ত ডেটা লোড করা। এটি ডেটা অ্যাক্সেস দ্রুত করতে পারে তবে অপ্রয়োজনীয় ডেটা লোড হওয়ার ঝুঁকি থাকে।
- Hibernate-এ
FetchType.EAGERব্যবহার করলে সম্পর্কিত সমস্ত ডেটা ইমিডিয়েটলি লোড হয়।
@OneToMany এবং @ManyToOne এর মাধ্যমে উদাহরণ
টেবিল সম্পর্কের সেটআপ
আমরা দুটি Entity ক্লাস নেব: Category এবং Product। একটি Category-এর অধীনে একাধিক Product থাকতে পারে।
Entity গুলো তৈরি
Category Entity:
import jakarta.persistence.*;
import java.util.List;
@Entity
public class Category {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "category", fetch = FetchType.LAZY) // Lazy Loading
private List<Product> products;
// Getters and Setters
}
Product Entity:
import jakarta.persistence.*;
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private Double price;
@ManyToOne(fetch = FetchType.EAGER) // Eager Loading
@JoinColumn(name = "category_id")
private Category category;
// Getters and Setters
}
Lazy Loading এর উদাহরণ
Lazy Loading এর সময় সম্পর্কিত ডেটা তখনই লোড হবে, যখন তা প্রথমবার অ্যাক্সেস করা হবে।
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CategoryService {
@Autowired
private CategoryRepository categoryRepository;
public void showCategoryWithProducts(Long categoryId) {
Category category = categoryRepository.findById(categoryId).orElse(null);
if (category != null) {
System.out.println("Category Name: " + category.getName());
// Lazy Loading: Products তখনই লোড হবে, যখন এটি অ্যাক্সেস করা হবে
List<Product> products = category.getProducts();
products.forEach(product -> System.out.println("Product Name: " + product.getName()));
}
}
}
সমস্যা:
Lazy Loading ব্যবহার করার সময় Session বন্ধ হয়ে গেলে LazyInitializationException হতে পারে।
Eager Loading এর উদাহরণ
Eager Loading এর সময় সম্পর্কিত সমস্ত ডেটা সরাসরি প্রথমবারেই লোড হয়।
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
public void showProductWithCategory(Long productId) {
Product product = productRepository.findById(productId).orElse(null);
if (product != null) {
System.out.println("Product Name: " + product.getName());
System.out.println("Category Name: " + product.getCategory().getName());
// Category ইতিমধ্যেই Eagerly লোড করা হয়েছে
}
}
}
সুবিধা:
Eager Loading ব্যবহার করলে LazyInitializationException এর ঝুঁকি নেই, কারণ সম্পর্কিত ডেটা লোড হওয়া নিশ্চিত।
Lazy এবং Eager Loading এর তুলনা
| বৈশিষ্ট্য | Lazy Loading | Eager Loading |
|---|---|---|
| ডেটা লোড টাইমিং | প্রয়োজন অনুযায়ী লোড হয়। | প্রথমবারেই সব সম্পর্কিত ডেটা লোড হয়। |
| পারফরম্যান্স | কম ডেটা লোড হওয়ায় দ্রুত। | বেশি ডেটা লোড হলে পারফরম্যান্স স্লো হতে পারে। |
| মেমরি ব্যবহার | কম মেমরি ব্যবহার করে। | বেশি মেমরি ব্যবহার করে। |
| LazyInitializationException | সম্ভাবনা থাকে। | থাকে না। |
সঠিক কৌশল নির্বাচন
- Lazy Loading: বড় ডেটাসেটের ক্ষেত্রে যেখানে সমস্ত ডেটা প্রয়োজন হয় না।
- Eager Loading: ছোট ডেটাসেটের ক্ষেত্রে বা যখন সমস্ত সম্পর্কিত ডেটা অবিলম্বে প্রয়োজন হয়।
Read more